package sendGoodsRecord

import (
	"context"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"gorm.io/gorm"
	"insighttracking/apps/purchase/auth"
	"insighttracking/common/utils"
	"insighttracking/query/dao"
	"insighttracking/query/model"
	"insighttracking/query/service"
	"net/http"

	"insighttracking/apps/purchase/internal/svc"
	"insighttracking/apps/purchase/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
	"os"
)

type CreateOutGoodsRecordApiLogic struct {
	logx.Logger
	ctx     context.Context
	svcCtx  *svc.ServiceContext
	Request *http.Request
}

func NewCreateOutGoodsRecordApiLogic(ctx context.Context, svcCtx *svc.ServiceContext, request *http.Request) *CreateOutGoodsRecordApiLogic {
	hostname, _ := os.Hostname()
	return &CreateOutGoodsRecordApiLogic{
		Logger: logx.WithContext(ctx).WithCallerSkip(0).WithFields(
			logx.Field("Log_UUID", uuid.New().String()),
			logx.Field("hostname", hostname)),
		ctx:     ctx,
		svcCtx:  svcCtx,
		Request: request,
	}
}

// CreateOutGoodsRecordApi 仓库出库是直接出库,如果有分拣的时候就按分拣出库,如果没有就按订单出库
func (l *CreateOutGoodsRecordApiLogic) CreateOutGoodsRecordApi(req *types.CreateSendGoodsRecordReq) (resp string, err error) {
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return "", err
	}
	// 创建出库数据
	tx := dao.Use(l.svcCtx.MysqlDb).Begin()
	for _, item := range req.IdList {
		_, err = service.OrdersService.GetByIdApi(l.ctx, item)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			if err = tx.Rollback(); err != nil {
				return "", err
			}
			return "", errors.New("传递的订单号错误")
		}
		_, err = service.SendGoodsRecordService.GetStoreSortingByOrderIdApi(l.ctx, item)
		if err == nil {
			if err = tx.Rollback(); err != nil {
				return "", errors.New("当前订单已出库,不能重复出库")
			}
			return "", errors.New("当前订单已出库,不能重复出库")
		}
		// 限制没有入库的订单不能出库
		var inStatus = service.PurchaseOrderService.GetPurchaseOrderStatusByOrderIdApi(l.ctx, item)
		fmt.Println(inStatus, "------------------inStatus------------------")
		if inStatus != 10 {
			if err = tx.Rollback(); err != nil {
				return "", errors.New("当前订单没有入库,不能出库")
			}
			return "", errors.New("当前订单没有入库,不能出库")
		}
		sortingEntity, err := service.StoreSortingService.GetStoreSortingByOrderIdApi(l.ctx, item)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			l.Logger.Infof("------------------当前订单没有分拣,走订单出库11------------------")
			// 没有分拣的订单
			ordersEntity, err := service.OrdersService.GetByIdApi(l.ctx, item)
			if errors.Is(err, gorm.ErrRecordNotFound) {
				if err = tx.Rollback(); err != nil {
					return "", err
				}
				return "", errors.New("传递的订单号错误")
			}
			var sendGoodsRecordData = model.SendGoodsRecordEntity{
				OrderNo:      utils.GenerateTodayOrderNo(l.svcCtx.RedisDb, "FJCK"), // 订单流水号
				EnterpriseID: ordersEntity.EnterpriseID,                            // 关联到enterprise表主键id
				CustomerID:   ordersEntity.CustomerID,                              // 客户id,关联到enterprise_customer表主键id
				TotalAmount:  ordersEntity.TotalAmount,                             // 订单金额
				TotalCount:   ordersEntity.TotalCount,                              // 订单商品数量
				WarehouseID:  ordersEntity.WarehouseID,                             // 发货单号,关联到warehouse表主键id
				OrdersID:     ordersEntity.ID,                                      // 关联到订单表id,orders表主键id
				OperateName:  accountInfo.PersonName,                               // 制单员
				OperateID:    accountInfo.PersonId,                                 // 制单员id,关联到员工表
				Remark:       "仓库操作-订单没有分拣直接出库",                                    // 备注
			}
			if err = service.SendGoodsRecordService.CreateApi(l.ctx, tx, &sendGoodsRecordData); err != nil {
				if err = tx.Rollback(); err != nil {
					return "", err
				}
				return "", errors.New("创建失败")
			}
			ordersDetailEntities, err := service.OrdersDetailService.GetByOrderIdListApi(l.ctx, []int64{item})
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return "", errors.New("传递的订单没有商品")
			}
			var sendGoodsRecordDetailData = make([]*model.SendGoodsRecordDetailEntity, 0)
			for _, detailEntity := range ordersDetailEntities {
				sendGoodsRecordDetailData = append(sendGoodsRecordDetailData, &model.SendGoodsRecordDetailEntity{
					SendGoodsRecordID:       sendGoodsRecordData.ID,               // 分拣单store_sorting主键id
					SpuID:                   detailEntity.SpuID,                   // 商品,关联到spu表主键id
					SnapshotSpuName:         detailEntity.SnapshotName,            // 快照商品名称
					SnapshotProductImageURL: detailEntity.SnapshotProductImageURL, // 快照产品图片
					SnapshotSpuType:         detailEntity.SnapshotSpuType,         // 快照商品类型,0表示基础商品,1表示加工商品
					SnapshotUnit:            detailEntity.SnapshotUnit,            // 快照单位
					SnapshotCategoryID:      detailEntity.SnapshotCategoryID,      // 快照分类id
					SnapshotCategory:        detailEntity.SnapshotCategory,        // 快照分类
					LossRate:                detailEntity.SnapshotLossRate,        // 快照损耗率
					OrdersCount:             detailEntity.SpuCount,                // 下单数量
					SnapshotPrice:           detailEntity.SnapshotPrice,           // 商品单价
					OutboundCount:           detailEntity.SpuCount,                // 出库数量
					OperateName:             accountInfo.PersonName,               // 出库员
					OperateID:               accountInfo.PersonId,                 // 出库员id,关联到员工表
					Remark:                  detailEntity.Remark,                  // 备注
				})
				//changeCount := detailEntity.SpuCount.Add(detailEntity.SpuCount.Mul(detailEntity.SnapshotLossRate))
				//// 扣减库存
				//if err = service.SpuInventoryService.ReduceInventoryApi(l.ctx, tx, accountInfo.EnterpriseId, ordersEntity.WarehouseID, detailEntity.SpuID, changeCount); err != nil {
				//	l.Logger.Errorf("扣减库存失败:%v", err)
				//	fmt.Println("11122?")
				//	if err = tx.Rollback(); err != nil {
				//		return "", err
				//	}
				//	return "", err
				//}
				//// 库存记录
				//if err = service.InventRecordService.CreateInventRecordApi(l.ctx, tx, &model.InventoryRecordEntity{
				//	EnterpriseID: accountInfo.EnterpriseId,                    // 关联到enterprise表主键id
				//	SpuID:        detailEntity.SpuID,                          // 商品主键,关联到spu表主键id
				//	Types:        1,                                           // 类型,0表示入库,1表示出库
				//	Source:       0,                                           // 来源,0表示正常出入口,10表示盘点报损报溢,20表调拨
				//	WarehouseID:  ordersEntity.WarehouseID,                    // 仓库id,关联到warehouse表主键id
				//	ChangeCount:  changeCount,                                 // 变动数量
				//	Price:        detailEntity.SnapshotPrice,                  // 单价
				//	Amount:       changeCount.Mul(detailEntity.SnapshotPrice), // 金额
				//}); err != nil {
				//	if err = tx.Rollback(); err != nil {
				//		return "", err
				//	}
				//	return "", errors.New("操作失败")
				//}
			}
			if err = service.SendGoodsRecordDetailService.CreateBatchApi(l.ctx, tx, sendGoodsRecordDetailData); err != nil {
				if err = tx.Rollback(); err != nil {
					return "", err
				}
				return "", errors.New("操作失败")
			}
		} else {
			l.Logger.Infof("------------------当前订单有分拣,走分拣出库22------------------")
			// 已经分拣的订单
			var sendGoodsRecordData = model.SendGoodsRecordEntity{
				OrderNo: utils.GenerateTodayOrderNo(l.svcCtx.RedisDb, "FJCK"), // 订单流水号

				EnterpriseID: accountInfo.EnterpriseId,  // 关联到enterprise表主键id
				CustomerID:   sortingEntity.CustomerID,  // 客户id,关联到enterprise_customer表主键id
				TotalAmount:  sortingEntity.TotalAmount, // 订单金额
				TotalCount:   sortingEntity.TotalCount,  // 订单商品数量
				WarehouseID:  sortingEntity.WarehouseID, // 发货单号,关联到warehouse表主键id
				OrdersID:     item,                      // 关联到订单表id,orders表主键id
				OperateName:  sortingEntity.OperateName, // 制单员
				OperateID:    sortingEntity.OperateID,   // 制单员id,关联到员工表
				Remark:       "仓库操作-订单分拣后出库",            // 备注
			}
			if err = service.SendGoodsRecordService.CreateApi(l.ctx, tx, &sendGoodsRecordData); err != nil {
				if err = tx.Rollback(); err != nil {
					return "", err
				}
				return "", errors.New("创建失败")
			}
			// 创建明细
			storeSortingDetailList, err := service.StoreSortingDetailService.GetStoreSortingDetailApi(l.ctx, sortingEntity.ID)
			if err != nil || len(storeSortingDetailList) == 0 {
				return "", errors.New("传递的订单没有分拣")
			}
			var sendGoodsRecordDetailData = make([]*model.SendGoodsRecordDetailEntity, 0)
			for _, detailEntity := range storeSortingDetailList {
				sendGoodsRecordDetailData = append(sendGoodsRecordDetailData, &model.SendGoodsRecordDetailEntity{
					SendGoodsRecordID:       sendGoodsRecordData.ID,               // 分拣单store_sorting主键id
					SpuID:                   detailEntity.SpuID,                   // 商品,关联到spu表主键id
					SnapshotSpuName:         detailEntity.SnapshotSpuName,         // 快照商品名称
					SnapshotProductImageURL: detailEntity.SnapshotProductImageURL, // 快照产品图片
					SnapshotSpuType:         detailEntity.SnapshotSpuType,         // 快照商品类型,0表示基础商品,1表示加工商品
					SnapshotUnit:            detailEntity.SnapshotUnit,            // 快照单位
					SnapshotCategoryID:      detailEntity.SnapshotCategoryID,      // 快照分类id
					SnapshotCategory:        detailEntity.SnapshotCategory,        // 快照分类
					LossRate:                detailEntity.LossRate,                // 快照损耗率
					OrdersCount:             detailEntity.OrdersCount,             // 下单数量
					SnapshotPrice:           detailEntity.SnapshotPrice,           // 商品单价
					OutboundCount:           detailEntity.OutboundCount,           // 出库数量
					OperateName:             detailEntity.OperateName,             // 出库员
					OperateID:               detailEntity.OperateID,               // 出库员id,关联到员工表
					Remark:                  detailEntity.Remark,                  // 备注
				})
				//changeCount := detailEntity.OutboundCount.Add(detailEntity.LossCount)
				//// 扣减库存
				//if err = service.SpuInventoryService.ReduceInventoryApi(l.ctx, tx, accountInfo.EnterpriseId, sortingEntity.WarehouseID, detailEntity.SpuID, changeCount); err != nil {
				//	l.Logger.Infof("出库失败:%v", err)
				//	if err = tx.Rollback(); err != nil {
				//		return "", err
				//	}
				//	return "", err
				//}
				//// 库存记录
				//if err = service.InventRecordService.CreateInventRecordApi(l.ctx, tx, &model.InventoryRecordEntity{
				//	EnterpriseID: accountInfo.EnterpriseId,                    // 关联到enterprise表主键id
				//	SpuID:        detailEntity.SpuID,                          // 商品主键,关联到spu表主键id
				//	Types:        1,                                           // 类型,0表示入库,1表示出库
				//	Source:       0,                                           // 来源,0表示正常出入口,10表示盘点报损报溢,20表调拨
				//	WarehouseID:  sortingEntity.WarehouseID,                   // 仓库id,关联到warehouse表主键id
				//	ChangeCount:  changeCount,                                 // 变动数量
				//	Price:        detailEntity.SnapshotPrice,                  // 单价
				//	Amount:       changeCount.Mul(detailEntity.SnapshotPrice), // 金额
				//}); err != nil {
				//	l.Logger.Infof("创建库存记录失败:%v", err)
				//	if err = tx.Rollback(); err != nil {
				//		return "", err
				//	}
				//	return "", errors.New("操作失败")
				//}
			}
			if err = service.SendGoodsRecordDetailService.CreateBatchApi(l.ctx, tx, sendGoodsRecordDetailData); err != nil {
				l.Logger.Errorf("创建出库详情记录失败:%v", err)
				if err = tx.Rollback(); err != nil {
					return "", err
				}
				return "", errors.New("操作失败")
			}
		}
	}
	if err = tx.Commit(); err != nil {
		return "", errors.New("创建失败")
	}
	return "操作成功", nil
}
